package com.zwj.multipledata.config;

import com.mysql.cj.jdbc.MysqlXADataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * CRM模块数据库配置类，用于多数据源环境下配置CRM相关数据源及MyBatis组件。
 */
@Configuration
@MapperScan(basePackages = {"com.zwj.multipledata.mapper.crm"}, sqlSessionFactoryRef = "crmSqlSessionFactory")
public class CrmDbConfig {
    @Value("${spring.datasource.crm.jdbc-url}")
    private String jdbcUrl;
    @Value("${spring.datasource.crm.username}")
    private String username;
    @Value("${spring.datasource.crm.password}")
    private String password;

    /**
     * 创建CRM数据源Bean，使用spring.datasource.crm前缀的配置属性。
     *
     * @return 配置好的数据源实例
     */
    @Bean(name = "crmDataSource")
    public DataSource dataSource() throws SQLException {
        MysqlXADataSource mysqlXADataSource = new MysqlXADataSource();
        mysqlXADataSource.setUrl(jdbcUrl);
        mysqlXADataSource.setUser(username);
        mysqlXADataSource.setPassword(password);
        mysqlXADataSource.setPinGlobalTxToPhysicalConnection(true);

        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSource(mysqlXADataSource);
        xaDataSource.setUniqueResourceName("crm");
        return xaDataSource;
    }

    /**
     * 配置事务管理器，确保CRM数据源的事务能够正常工作。
     *
     * @return 数据源事务管理器实例
     */
    @Bean
    public PlatformTransactionManager transactionManager() throws SQLException {
        return new DataSourceTransactionManager(this.dataSource());
    }

    /**
     * 创建CRM模块的SqlSessionFactory，并配置相关参数。
     *
     * @param dataSource 注入通过@Qualifier指定的CRM数据源
     * @return 配置完成的SqlSessionFactory实例
     * @throws Exception 如果初始化失败则抛出异常
     */
    @Primary
    @Bean(name = "crmSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("crmDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 设置数据源
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 指定mapper文件位置
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/crm/*.xml"));
        // 设置实体类包路径，自动映射别名
        sqlSessionFactoryBean.setTypeAliasesPackage("com.zwj.multipledata.mapper.crm");
        // 开启驼峰命名转换，将数据库字段下划线格式转换为Java对象的驼峰格式
        sqlSessionFactoryBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
        return sqlSessionFactoryBean.getObject();
    }
}